home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Sample Code / Games / MoofWars / MoofWars Encoder 8⁄15⁄96 / •Sources / GridEncode.cp < prev    next >
Encoding:
Text File  |  1996-08-19  |  8.3 KB  |  282 lines  |  [TEXT/CWIE]

  1. /*************************************************************************************
  2. #
  3. #    GridEncode.cp
  4. #
  5. #   This is just a very simple encoder that shows how to build GRID and TILE resources.
  6. #    The TILE resource is a set of 32x32x1 byte tiles.  This encoder takes a picture and
  7. #   dices it into 32x32 tiles, which it writes out to output file.  It then builds a
  8. #   standard grid, repeating the original picture as a pattern across the grid.
  9. #
  10. #   Eventually, it would be nice to make a program that lets someone graphically edit
  11. #   the available list of tiles and the actual GRID resource, much like any number
  12. #   of map editors out for various games.
  13. #
  14. #    Author: Timothy Carroll
  15. #    Apple Developer Technical Support
  16. #    timc@apple.com
  17. #
  18. #    Modification History: 
  19. #
  20. #    8/15/96        TMC     Initial Release
  21. #
  22. #    Copyright © 1996 Apple Computer, Inc., All Rights Reserved
  23. #
  24. #
  25. #    You may incorporate this sample code into your applications without
  26. #    restriction, though the sample code has been provided "AS IS" and the
  27. #    responsibility for its operation is 100% yours.  However, what you are
  28. #    not permitted to do is to redistribute the source as "DSC Sample Code"
  29. #    after having made changes. If you're going to re-distribute the source,
  30. #    we require that you make it clear in the source that the code was
  31. #    descended from Apple Sample Code, but that you've made changes.
  32. #
  33. *************************************************************************************/
  34.  
  35. #include "GridEncode.h"
  36. #include "GridTilesFormat.h"
  37.  
  38.  
  39. OSStatus GridTileEncode (short inputFileResNum, short outputFileResNum)
  40. {
  41.     OSStatus        theErr;
  42.     short            saveResNum;
  43.     
  44.     // Used to compile the tile resource
  45.     PicHandle        tilePict = NULL;
  46.     GWorldPtr        tileWorld = NULL;
  47.     PixMapHandle    tilePix = NULL;
  48.     
  49.     CGrafPtr         savePort;
  50.     GDHandle         saveDevice;
  51.     
  52.     Rect            pictRect;
  53.  
  54.     long            width, height, numTiles;
  55.     long            tileRowBytes;
  56.     Ptr                tileBaseAddress;
  57.     
  58.     long            x, y, loop;
  59.     
  60.     Ptr                destPtr, srcPtr;
  61.     CellGridType    *gridPtr;
  62.     CellGridType    currentValue;
  63.     
  64.     // Our output handles
  65.     Handle            tile = NULL;
  66.     Handle            grid = NULL;
  67.     
  68.     // Whether or not we've written it out as a resource
  69.     Boolean            tileIsResource = false, gridIsResource = false;
  70.         
  71.     saveResNum = CurResFile();
  72.  
  73.     UseResFile (inputFileResNum);
  74.  
  75.  
  76.     // First thing is to copy the color table resource to the output.
  77.     theErr = CopyResource (inputFileResNum, outputFileResNum,'clut', kAppColorTableResID);
  78.     FAIL_OSERR (theErr, "\pFailed to copy the color table to the destination file")
  79.  
  80.     // Load the color table and the graphic we want to dice into pieces
  81.     gAppColorTable = GetCTable( kAppColorTableResID );
  82.     FAIL_NIL (gAppColorTable, "\pFailed to load the color table")
  83.     
  84.     tilePict = (PicHandle) Get1Resource ('PICT', kPICTInputResID);
  85.     theErr = ResError();
  86.     FAIL_OSERR (theErr, "\pFailed to load the pict")
  87.     FAIL_NIL (tilePict, "\pFailed to load the pict")
  88.  
  89.  
  90.     
  91.     // Create a GWorld and draw our PICT into it.
  92.     
  93.     pictRect = (**tilePict).picFrame;
  94.     
  95.     pictRect.right -= pictRect.left;
  96.     pictRect.left = 0;
  97.     pictRect.bottom -= pictRect.top;
  98.     pictRect.top = 0;
  99.     
  100.     theErr = NewGWorld(&tileWorld, kPreferredDepth, &pictRect, gAppColorTable, NULL, keepLocal);
  101.     FAIL_OSERR (theErr, "\pCouldn't allocate GWorld for encoding")
  102.     FAIL_NIL (tileWorld, "\pCouldn't allocate GWorld for encoding")
  103.     
  104.     tilePix  = GetGWorldPixMap(tileWorld);
  105.     FAIL_NIL (tilePix, "\pCouldn't get the GWorld's PixMap")
  106.     FAIL_FALSE ( LockPixels(tilePix), "\pCouldn't lock GWorld PixMap")
  107.     
  108.     GetGWorld (&savePort, &saveDevice);
  109.     SetGWorld (tileWorld, NULL);
  110.     
  111.     EraseRect (&pictRect);
  112.     DrawPicture (tilePict, &pictRect);
  113.     
  114.     SetGWorld (savePort, saveDevice);
  115.  
  116.     // We're done with the picture, release it
  117.     ReleaseResource ((Handle) tilePict);
  118.     tilePict = NULL;
  119.  
  120.     // Time to build the tile resource.  We're going to dice it into as many
  121.     // 32x32 tiles as we can.  Any partial data to the bottom or the right will
  122.     // be ignored -- we only build complete tiles.
  123.     
  124.     width = pictRect.right / 32;
  125.     height = pictRect.bottom / 32;
  126.     numTiles = width * height + 1;  // Our first tile is always an all black tile, for the "borders"
  127.     
  128.     tile = NewHandleClear (sizeof (TileCollectionResHeader) + numTiles*kTileSize);
  129.     theErr = MemError();
  130.     FAIL_OSERR (theErr, "\p Failed to create the tile resource file")
  131.     FAIL_NIL (tile, "\p Failed to create the tile resource file")
  132.  
  133.     // Fill in the tile header.
  134.     (**((TileCollectionResHeader **) tile)).version = 0;
  135.     (**((TileCollectionResHeader **) tile)).depth = kPreferredDepth;
  136.     (**((TileCollectionResHeader **) tile)).flags = 0;
  137.     (**((TileCollectionResHeader **) tile)).numTiles = numTiles;
  138.     
  139.     tileBaseAddress = ( Ptr) GetPixBaseAddr( tilePix );
  140.     tileRowBytes = ( **tilePix ).rowBytes & 0x3fff;
  141.     
  142.     destPtr = (*tile) + sizeof (TileCollectionResHeader);
  143.     
  144.     // First tile, we just fill with black
  145.     for (loop = 0; loop < 32; loop++)
  146.     {
  147.         ((UInt32 *) destPtr)[0] = 0xFFFFFFFF;
  148.         ((UInt32 *) destPtr)[1] = 0xFFFFFFFF;
  149.         ((UInt32 *) destPtr)[2] = 0xFFFFFFFF;
  150.         ((UInt32 *) destPtr)[3] = 0xFFFFFFFF;
  151.         ((UInt32 *) destPtr)[4] = 0xFFFFFFFF;
  152.         ((UInt32 *) destPtr)[5] = 0xFFFFFFFF;
  153.         ((UInt32 *) destPtr)[6] = 0xFFFFFFFF;
  154.         ((UInt32 *) destPtr)[7] = 0xFFFFFFFF;
  155.         destPtr += 32;
  156.     }
  157.  
  158.     // Iterate over each tile and copy 1K of data to the destination
  159.     for (x = 0; x < width; x++)
  160.     {
  161.         for (y = 0; y < height; y++)
  162.         {
  163.             srcPtr = tileBaseAddress + 32*y*tileRowBytes + 32*x;
  164.             for (loop = 0; loop < 32; loop++)
  165.             {
  166.                 register UInt32 temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
  167.                 temp1 = ((UInt32 *) srcPtr)[0];
  168.                 temp2 = ((UInt32 *) srcPtr)[1];
  169.                 temp3 = ((UInt32 *) srcPtr)[2];
  170.                 temp4 = ((UInt32 *) srcPtr)[3];
  171.                 temp5 = ((UInt32 *) srcPtr)[4];
  172.                 temp6 = ((UInt32 *) srcPtr)[5];
  173.                 temp7 = ((UInt32 *) srcPtr)[6];
  174.                 temp8 = ((UInt32 *) srcPtr)[7];
  175.                 ((UInt32 *) destPtr)[0] = temp1;
  176.                 ((UInt32 *) destPtr)[1] = temp2;
  177.                 ((UInt32 *) destPtr)[2] = temp3;
  178.                 ((UInt32 *) destPtr)[3] = temp4;
  179.                 ((UInt32 *) destPtr)[4] = temp5;
  180.                 ((UInt32 *) destPtr)[5] = temp6;
  181.                 ((UInt32 *) destPtr)[6] = temp7;
  182.                 ((UInt32 *) destPtr)[7] = temp8;
  183.                 srcPtr += tileRowBytes;
  184.                 destPtr += 32;
  185.             }
  186.         }
  187.     }
  188.     
  189.     // Tile resource is done.  Dispose of the GWorld
  190.     DisposeGWorld ( tileWorld);
  191.     tileWorld = NULL;
  192.     
  193.     
  194.     // Time to create the GRID resource
  195.     grid = NewHandle (sizeof (TileGridResHeader) + 
  196.                             sizeof (CellGridType)*kGridWidth*kGridHeight);
  197.     theErr = MemError();
  198.     FAIL_OSERR (theErr, "\p Failed to allocate memory for GRID resource")
  199.     FAIL_NIL (grid, "\p Failed to allocate memory for GRID resource")
  200.     
  201.     // Fill in the header
  202.     (**((TileGridResHeader **) grid)).version = 0;
  203.     (**((TileGridResHeader **) grid)).flags = 0;
  204.     (**((TileGridResHeader **) grid)).tileResID = kOutputResID;
  205.     (**((TileGridResHeader **) grid)).width = kGridWidth;
  206.     (**((TileGridResHeader **) grid)).height = kGridHeight;
  207.     (**((TileGridResHeader **) grid)).defaultTile = 0;  // our black tile
  208.     
  209.     // Point to the start of the grid data.
  210.     gridPtr = (CellGridType * ) ((Ptr)(*grid) + sizeof (TileGridResHeader));
  211.     
  212.     // Fill in each tile
  213.     for (x = 0; x < kGridWidth; x++)
  214.     {
  215.         for (y = 0; y < kGridWidth; y++)
  216.         {
  217.             currentValue = (y % height)*height + (x % width) +1;
  218.             *gridPtr = currentValue;
  219.             gridPtr++;
  220.         }
  221.     }
  222.  
  223.     // Write the resources out to the output file.
  224.     UseResFile (outputFileResNum);
  225.     
  226.     AddResource( tile, TileCollectionResType, kOutputResID, "\p" );
  227.     theErr = ResError();
  228.     FAIL_OSERR (theErr, "\pFailed to add the TILE resource to the file")
  229.     tileIsResource = true;  
  230.     
  231.     WriteResource( tile );
  232.     theErr = ResError();
  233.     FAIL_OSERR (theErr, "\pFailed to write the TILE resource to the file")
  234.     
  235.     ReleaseResource( tile );
  236.     tile = NULL;
  237.  
  238.     AddResource( grid, TileGridResType, kOutputResID, "\p" );
  239.     theErr = ResError();
  240.     FAIL_OSERR (theErr, "\pFailed to add the GRID resource to the file")
  241.     gridIsResource = true;
  242.     
  243.     WriteResource( grid );
  244.     FAIL_OSERR (theErr, "\pFailed to write the GRID resource to the file")
  245.     theErr = ResError();
  246.     
  247.     ReleaseResource( grid );
  248.     grid = NULL;
  249.  
  250.         
  251.     // Build the grid resource;
  252.     
  253.     goto cleanup;
  254.     
  255.     error:
  256.     if (theErr == noErr)
  257.         theErr = paramErr;
  258.         
  259.     cleanup:
  260.     
  261.     UseResFile (saveResNum);
  262.     
  263.     if (tilePict != NULL)
  264.         ReleaseResource ((Handle) tilePict);
  265.     if (tileWorld != NULL)
  266.         DisposeGWorld (tileWorld);
  267.     if (gAppColorTable != NULL)
  268.         DisposeCTable (gAppColorTable);
  269.     if (tile)
  270.         if (tileIsResource)
  271.             ReleaseResource (tile);
  272.         else
  273.             DisposeHandle (tile);
  274.     if (grid)
  275.         if (gridIsResource)
  276.             ReleaseResource (grid);
  277.         else
  278.             DisposeHandle (grid);
  279.     gAppColorTable = NULL;
  280.     return theErr;
  281. }
  282.